package java_thinking.unit_15._15_7;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description :   引入类型标签就可以使用动态的isInstance()
 *                  未引入前在方法内部使用对象的.getClass并不能得到相关类型信息
 *
 *                  E21
 * @author: cww
 * @DateTime: 2019/4/4 9:02
 */
class Building {}
class House extends Building {}
/**
 * @author asd730520@live.com
 */
public class ClassTypeCapture<T> {
    Class<?> kind;
    public ClassTypeCapture(Class<?> kind) {
        this.kind = kind;
    }
    public boolean f(Object arg){
        return kind.isInstance(arg);
    }
    Map<String,Class<?>> map;

    public ClassTypeCapture(Class<?> kind,Map<String,Class<?>> map){
        this.kind = kind;
        this.map = map;
    }

    public void addType(String typeName,Class<?> kind) {
        map.put(typeName,kind);
    }

    public Object createNew(String typeName) throws IllegalAccessException, InstantiationException {
        if (map.containsKey(typeName)){
            return map.get(typeName).newInstance();
        }
        System.out.print(typeName+"class not available");
        return null;
    }

    public static void main(String[] args) {
        ClassTypeCapture<Building> ctl = new ClassTypeCapture<>(Building.class);
        System.out.print(ctl.f(new Building()));
        System.out.print(ctl.f(new House()));
        ClassTypeCapture<House> ctl2 = new ClassTypeCapture<>(House.class);
        //这里注意isInstance获取不到House父类
        System.out.print(ctl2.f(new Building()));
        System.out.print(ctl2.f(new House()));
        ClassTypeCapture<Building> ct = new ClassTypeCapture<>(Building.class,new HashMap<>());
        ct.addType("House",House.class);
        ct.addType("Building",Building.class);
        System.out.print("ct.ap"+ct.map);
        try {
            Building b = (Building)ct.createNew("Building");
            House h = (House)ct.createNew("House");
            System.out.print("b.getClass().getName(): ");
            System.out.println(b.getClass().getName());
            System.out.print("h.getClass().getName(): ");
            System.out.println(h.getClass().getName());
            System.out.print("House h is instance House: ");
            System.out.println(h instanceof House);
            System.out.print("House h is instance of Building: ");
            System.out.println(h instanceof Building);
            System.out.print("Building b is instance of House: ");
            System.out.println(b instanceof House);
            ct.createNew("String");  // String class not available
        } catch(IllegalAccessException e) {
            System.out.println("IllegalAccessException in maindemo");
        } catch(InstantiationException e) {
            System.out.println("InstantiationException in maindemo");
        }
    }
}
